/* 8911106 302933981 Ofri Keidar */

/******************************************************************************
* Student Name: Ofri Keidar
* Exercise Name: Ex6
* File Description: Class Inventory's interface. The class represents store's
* 					inventory. Class allows adding new item to catalog, ordering
* 					existing items, receiving ordered stock and selling items
******************************************************************************/


#ifndef INVENTORY_H_
#define INVENTORY_H_
#include <map>
#include "Item.h"
#include "Order.h"
#include "Sale.h"
#include "DeAmortArray.h"
#include "MyAuto_ptr.h"
#include "ItemExistsError.h"
#include "NoItemError.h"
#include "TooManyOrderedError.h"
#define INIT_ORDER_NUM 1 // used to initialize first order's number
#define MAX_AMOUNT_DIFF 10 // maximal difference allowed between ordered amount and amount in stock
#define BALANCE_AMOUNT 20 // amount to be balanced to if ordered more items than held in stock

class Inventory {
private:

	map<short, MyAuto_ptr<Item> > m_catalog; // a key is item number and a value is the item
	map<short, int> m_stock; // a key is item number and a value is how many items with this number are in stock
	map<int, MyAuto_ptr<Order> > m_orderTracker; // used to store orders
	DeAmortArray<Sale> m_salesDoc; // array of sales, used to document sales

	/***************************************************************************************
	* function name: Inventory(const Inventory& inventoryToCopy)
	* The Input: Inventory object to be copied
	* The output: None
	* The Function operation: Empty implementation since Inventory object should not be
	* 				          copied
	***************************************************************************************/
	Inventory(const Inventory& inventoryToCopy) { }

public:
	/***************************************************************************************
	* function name: Inventory()
	* The Input: None
	* The output: None
	* The Function operation: Creates a new Inventory object. Empty implementation since
	* 						  Inventory's members are not dynamically allocated
	***************************************************************************************/
	Inventory() { }

	/***************************************************************************************
	* function name: ~Inventory()
	* The Input: None
	* The output: None
	* The Function operation: Destructs Inventory object. Empty implementation since
	* 						  Inventory's members are not dynamically allocated
	***************************************************************************************/
	~Inventory() { }

	/***************************************************************************************
	* function name: void addItem(const short itemNumber, const string name) throw (ItemExistsError, bad_alloc)
	* The Input: Number and name for a new item
	* The output: None
	* The Function operation: If an item with given number does not exist, creates a new
	* 						  item with given number and name and adds it to inventory.
	* 						  Otherwise, item's number is thrown as an exception and item
	* 						  is not created
	***************************************************************************************/
	void addItem(const short itemNumber, const string name) throw (ItemExistsError, bad_alloc);

	/***************************************************************************************
	* function name: void orderStock(const short itemNum, const unsigned short amount) throw (NoItemError, bad_alloc)
	* The Input: Number of item to be ordered and amount if items
	* The output: None
	* The Function operation: If item exist in catalog, creates a new order and keeps it
	* 					      in order tracker.
	* 					      Otherwise, throws item's number as an exception and order
	* 					      is not created
	***************************************************************************************/
	void orderStock(const short itemNum, const unsigned short amount) throw (NoItemError, bad_alloc);

	/***************************************************************************************
	* function name: void recieveStock(const int orderNum, const unsigned short amount)
	* The Input: Number of order and amount of items received
	* The output: None
	* The Function operation: Updates order's details in order tracker. If no more items are
	* 					      to be ordered, order is erased from tracker.  Item's amount in
	* 					      stock is updated
	***************************************************************************************/
	void recieveStock(const int orderNum, const unsigned short amount);

	/***************************************************************************************
	* function name: void sellItem(const short itemNum, const int amount) throw (NoItemError, TooManyOrderedError, bad_alloc)
	* The Input: Item number and amount of items to be sold
	* The output: None
	* The Function operation: If given item number does exist in catalog, exception is thrown
	* 					      and item is not sold.
	* 					      If item's amount in stock is lower than wanted amount in
	* 					      more than 10, exception is thrown and item is not sold.
	* 					      If item's amount in stock is lower than wanted amount in 10 or
	* 					      less, item is sold and a new order is made so after order item's
	* 					      amount in stock will be 20.
	* 					      If item is sold, sale is documented
	***************************************************************************************/
	void sellItem(const short itemNum, const int amount) throw (NoItemError, TooManyOrderedError, bad_alloc);

	/***************************************************************************************
	* function name: void printSaleDoc() const
	* The Input: None
	* The output: None
	* The Function operation: Prints each sale's documentation from the earliest to the latest
	***************************************************************************************/
	void printSaleDoc() const;
};


#endif
